package com.tjsoft.demo.webChat.action;

import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Date;

import javax.servlet.ServletInputStream;

import org.apache.log4j.Logger;

import com.thoughtworks.xstream.XStream;
import com.tjsoft.demo.webChat.model.InMessage;
import com.tjsoft.demo.webChat.model.OutMessage;
import com.tjsoft.demo.webChat.model.TextOutMessage;
import com.tjsoft.demo.webChat.operator.MessageProcessingHandler;
import com.tjsoft.demo.webChat.util.Tools;
import com.tjsoft.demo.webChat.util.XStreamFactory;

public class WebChatAction extends BaseAction {
	private final Logger	logger			= Logger.getLogger(WebChatAction.class);
	private  String	 _token="weixin";
	private  String  signature;
	private  String  timestamp;
	private  String  nonce ;
	private  String  echostr;
	public void valid() throws Exception{
		  String path = request.getServletPath();
		  String pathInfo = path.substring(path.lastIndexOf("/"));
		 Boolean isGet = request.getMethod().equals("GET");
		 echostr = request.getParameter("echostr");//验证
		 signature = request.getParameter("signature");// 微信加密签名
	     timestamp = request.getParameter("timestamp");// 时间戳
		 nonce = request.getParameter("nonce");// 随机数
		// _token =pathInfo.substring(1);//获取的token验证
		if(null==echostr||echostr.isEmpty()){		   
			   response.getWriter().write("null");		   
		}else{//判断执行POStOrGet
			 if(isGet){
				 doGet();
			 }else{
			    doPost();
			 }
			
		}
	}
	/**
	 * 第一次用get方法请求验证token,是否建立和微信服务器的连接
	 * @throws IOException
	 */
	public void doGet() throws IOException{
		// 验证
		if (Tools.checkSignature(_token, signature, timestamp, nonce)) {
			logger.info("token验证成功");
		 	response.getWriter().write(echostr);
		}
	}
	public void doPost() throws IOException{
		  logger.info("doPost");
		 response.setCharacterEncoding("UTF-8");
		 response.setContentType("text/xml");
		 OutMessage oms=new OutMessage();
		 ServletInputStream in=request.getInputStream();//获取输入流,来自POST发送的xml
		 XStream xs=XStreamFactory.init(false);//不开启D
		 xs.alias("xml", InMessage.class);
		 String xmlMsg=Tools.inputStream2String(in);//将输入流转换成字符串
		 System.out.println("输入消息是：["+xmlMsg+"]");
		 
		 InMessage msg=(InMessage)xs.fromXML(xmlMsg);//将输入字符串映射到输入出对象
		  logger.info("输入消息是：["+xmlMsg+"]");
		 //h获取消息处理器
		 try{
			 String handler="com.tjsoft.demo.webChat.operator.impl.MessageProcessingHandlerImpl";
			 Class<?> clazz=Class.forName(handler);
			 MessageProcessingHandler  processingHandler =(MessageProcessingHandler) clazz.newInstance();
			 //取得消息类型
			String type=msg.getMsgType();
			Method mt=clazz.getMethod(type+"TypeMsg", InMessage.class);
			//将类型添加到outMessage中
			oms=(OutMessage)mt.invoke(processingHandler, msg);
			if(oms==null){
				  logger.info("oms为null");
				oms=new TextOutMessage();
				((TextOutMessage)oms).setContent("系统错误");
			}
			//调用设置返回信息函数
			setMsgInfo(oms, msg);
		   }catch(Exception e){
			   logger.error("获取消息处理函数发送异常");
				oms = new TextOutMessage();
				((TextOutMessage) oms).setContent("系统错误!");
				try {
					setMsgInfo(oms,msg);
				} catch (Exception e1) {
				}
		 }
		  //把发送对象转换成xml输出
		 xs=XStreamFactory.init(true);
		 xs.alias("xml", oms.getClass());
		 // xs.alias("item", ) 图文信息
		 String xml=xs.toXML(oms);
		 System.out.println("输出消息：["+xml+"]");
		  logger.info("输出消息：["+xml+"]");
		 response.getWriter().write(xml);
		 }
	/**
	 * 根据输入信息，设置发送消息
	 * @param oms
	 * @param msg
	 * @throws SecurityException 
	 * @throws NoSuchFieldException 
	 * @throws IllegalAccessException 
	 * @throws IllegalArgumentException 
	 */
    private void setMsgInfo(OutMessage oms,InMessage msg) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException{   	
    	Class<?> outMsg=oms.getClass().getSuperclass();
    	Field CreateTime=outMsg.getDeclaredField("CreateTime");//获取属性
    	Field ToUserName=outMsg.getDeclaredField("ToUserName"); 
    	Field FromUserName=outMsg.getDeclaredField("FromUserName");
    	//设置属性访问权限
    	ToUserName.setAccessible(true);
    	CreateTime.setAccessible(true);
    	FromUserName.setAccessible(true);   	
    	//给输出对象赋值
    	CreateTime.set(oms,new Date().getTime());
    	ToUserName.set(oms, msg.getFromUserName());
    	FromUserName.set(oms, msg.getToUserName());
    }
}
